package com.wejoy.video.middle.station.admin.controller.system;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.wejoy.video.middle.station.admin.controller.BaseController;
import com.wejoy.video.middle.station.admin.util.CurrentUserUtils;
import com.wejoy.video.middle.station.data.annotation.RoleCheck;
import com.wejoy.video.middle.station.data.domain.PageResult;
import com.wejoy.video.middle.station.data.domain.system.SysCarmera;
import com.wejoy.video.middle.station.data.domain.system.SysDept;
import com.wejoy.video.middle.station.data.domain.system.SysDeptUserNotice;
import com.wejoy.video.middle.station.data.domain.system.SysUser;
import com.wejoy.video.middle.station.data.domain.workorder.WorkOrderInfo;
import com.wejoy.video.middle.station.data.domain.workorder.WorkOrderProcess;
import com.wejoy.video.middle.station.data.domain.workorder.WorkOrderReview;
import com.wejoy.video.middle.station.data.enums.dict.*;
import com.wejoy.video.middle.station.data.exception.BusinessException;
import com.wejoy.video.middle.station.data.service.evs.IEvsHttpService;
import com.wejoy.video.middle.station.data.service.system.ISysCarmeraService;
import com.wejoy.video.middle.station.data.service.system.ISysDeptService;
import com.wejoy.video.middle.station.data.util.LoginUtil;
import com.wejoy.video.middle.station.data.util.StringUtils;
import com.wejoy.video.middle.station.data.util.WJAssert;
import com.wejoy.video.middle.station.data.vo.RespJSON;
import com.wejoy.video.middle.station.data.vo.api.DeptPointVO;
import com.wejoy.video.middle.station.data.vo.api.EvsUserVO;
import com.wejoy.video.middle.station.data.vo.evsapi.EvsApiDeptVO;
import com.wejoy.video.middle.station.data.vo.system.SysRoleResourceVO;
import com.wejoy.video.middle.station.data.vo.workorder.DeptExcelVO;
import com.wejoy.video.middle.station.data.vo.workorder.WorkorderExcelVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统-部门表
 *
 * @author admin
 * @date 2021年11月16日 09:59:50
 */
@RestController
@RequestMapping("/system/sysDept")
public class SysDeptController extends BaseController {

    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private IEvsHttpService evsHttpService;
    @Autowired
    private ISysCarmeraService sysCarmeraService;

    /**
     * 保存或更新
     *
     * @param sysDeptReq sysDeptReq
     * @return RespJSON
     */
    @PostMapping("/save")
    @RoleCheck(name = "sys_dept_add,sys_dept_edit")
    public RespJSON save(@RequestBody SysDept sysDeptReq, @SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser) {
        sysDeptService.save(sysDeptReq, loginSysUser.getUserName());
        return RespJSON.success();
    }


    @PostMapping("/getDepList")
    @RoleCheck(name = "sys_dept_list")
    public RespJSON getDepList(@RequestBody SysDept evsApiDeptReq,@SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser) {
        evsApiDeptReq.setParentId(-1);
        evsApiDeptReq.setIncludeLower(true);
        List<SysDept> departments = evsHttpService.getDepartments(evsApiDeptReq, loginSysUser.getToken());
        List<SysDept> result=new ArrayList<>();
        departments.forEach(item->{
            SysDept sysDept = new SysDept();
            sysDept.setDeptType(evsApiDeptReq.getDeptType());
            sysDept.setCameraType(evsApiDeptReq.getCameraType());
            List<SysDept> serviceList = sysDeptService.getList(sysDept);
            Optional<SysDept> first = serviceList.stream()
                    .filter(de -> de.getId().equals(item.getId()))
                    .findFirst();
            if(first.isPresent()){
                item.setLatitude(first.get().getLatitude());
                item.setDeptType(first.get().getDeptType());
                item.setLongitude(first.get().getLongitude());
                item.setIsAbnormal(first.get().getIsCarmerOffline()||first.get().getIsAlarmStatus());
                if(item.getIsAbnormal()){
                    SysCarmera sysCarmera = new SysCarmera();
                    sysCarmera.setOnline(false);
                    sysCarmera.setDepId(first.get().getId());
                    item.setCameraOffLineCount(sysCarmeraService.getCount(sysCarmera));
                }else {
                    item.setCameraOffLineCount(0);
                }
                result.add(item);
            }
        });
        return RespJSON.success(result);
    }

    @PostMapping("/getDeptList")
    @RoleCheck(name = "sys_dept_list")
    public RespJSON getDeptList(@RequestBody SysDept evsApiDeptReq,@SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser) {
        List<SysDept> departments = evsHttpService.getDepartments(evsApiDeptReq, loginSysUser.getToken());
        departments.forEach(item->{
            SysDept sysDept = sysDeptService.getOneById(item.getId());
            if(sysDept!=null){
                sysDept.setName(item.getName());
                sysDept.setLeaf(item.getLeaf());
                if(!StringUtils.isEmpty(sysDept.getUserId())){
                    String[] userIds = sysDept.getUserId().split(",");
                    ArrayList<SysUser> users = new ArrayList<>();
                    for (String userId : userIds) {
                        JSONObject userJson = evsHttpService.getUserById(Long.valueOf(userId), loginSysUser.getToken());
                        SysUser sysUser = new SysUser();
                        sysUser.setId(userJson.getLong("id"));
                        sysUser.setName(userJson.getString("name"));
                        sysUser.setTel(userJson.getString("tel"));
                        users.add(sysUser);
                    }
                    sysDept.setUsers(users);
                }
                BeanUtils.copyProperties(sysDept,item);
            }
        });
        return RespJSON.success(departments);
    }

    /**
     * 主键查询
     *
     * @param id id
     * @return RespJSON
     */
    @RequestMapping("/getOneById")
    @RoleCheck(name = "sys_dept_list")
    public RespJSON getOneById(Long id,@SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser) {
        SysDept sysDept = sysDeptService.getOneById(id);
        if(ObjectUtils.isEmpty(sysDept)){
            return RespJSON.success(new SysDept());
        }
        if(!StringUtils.isEmpty(sysDept.getUserId())){
            String[] userIds = sysDept.getUserId().split(",");
            ArrayList<SysUser> users = new ArrayList<>();
            for (String userId : userIds) {
                JSONObject userJson = evsHttpService.getUserById(Long.valueOf(userId), evsHttpService.getToken());
                SysUser sysUser = new SysUser();
                sysUser.setId(userJson.getLong("id"));
                sysUser.setName(userJson.getString("name"));
                sysUser.setTel(userJson.getString("tel"));
                users.add(sysUser);
            }
            sysDept.setUsers(users);
        }
        return RespJSON.success(sysDept);
    }

    @PostMapping("/getDepTreeList")
    public RespJSON getDepTreeList(@RequestBody SysDept evsApiDeptReq,@SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser) {
        SysDept evsApiDept = new SysDept();
        evsApiDept.setParentId(-1);
        evsApiDept.setIncludeLower(true);
        evsApiDept.setName(evsApiDeptReq.getName());
        return RespJSON.success(sysDeptService.convertToDesiredFormat(evsHttpService.getDepartmentsJson(evsApiDept, loginSysUser.getToken())));
    }

    /**
     * 获取部门树
     * @return
     * @throws IOException
     */
    @ResponseBody
    @GetMapping("/getDeptTree")
    public RespJSON getDeptTree(Integer parentId,Boolean includeLower,Integer screenType,Integer isMonitor,@SessionAttribute(CurrentUserUtils.SYSTEM_USER) SysUser loginSysUser){
        SysDept evsApiDept = new SysDept();
        evsApiDept.setParentId(parentId);
        evsApiDept.setIncludeLower(includeLower==null?false:includeLower);
        String token = loginSysUser.getToken();
        if(screenType ==null || screenType==0){
            token = evsHttpService.getToken();
        }
        List<DeptPointVO> deptPointVOS = JSONArray.parseArray(JSONObject.toJSONString(evsHttpService.getDepartmentsJson(evsApiDept, token)), DeptPointVO.class);
        if(CollectionUtils.isEmpty(deptPointVOS)){
            return RespJSON.success(deptPointVOS);
        }
        if(EnumYesNo.YES.getCode()==isMonitor){
            for (DeptPointVO datum : deptPointVOS) {
                JSONObject points = evsHttpService.getPoints(token, 50, 1, datum.getId(),null,null);
                JSONArray data = points.getJSONArray("data");
                if(data==null||data.size()==0){
                    datum.setCheckPoint(false);
                    datum.setPoint(new JSONArray());
                }else {
                    datum.setPoint(data);
                    datum.setCheckPoint(true);
                }
            }
        }
        return RespJSON.success(buildDeptTree(deptPointVOS));
    }

    public List<DeptPointVO> buildDeptTree(List<DeptPointVO> deptPointVOS) {
        // 1. 构建一个以 id 为键的 Map
        Map<Integer, DeptPointVO> idToNodeMap = deptPointVOS.stream()
                .collect(Collectors.toMap(DeptPointVO::getId, node -> node));

        // 2. 初始化树形结构
        List<DeptPointVO> rootNodes = new ArrayList<>();

        // 3. 构建树形结构
        for (DeptPointVO node : deptPointVOS) {
            BigInteger parentId = node.getParentId();
            if (parentId == null || !idToNodeMap.containsKey(parentId.intValue())) {
                // 如果没有父节点，则为根节点
                rootNodes.add(node);
            } else {
                // 有父节点，添加到父节点的子节点列表中
                DeptPointVO parent = idToNodeMap.get(parentId.intValue());
                if (parent.getChildren() == null) {
                    parent.setChildren(new ArrayList<>());
                }
                parent.getChildren().add(node);
                parent.setLeaf(false); // 标记为非叶子节点
            }
        }

        return rootNodes;
    }


    /**
     * 下载excel文件
     */
    @GetMapping("/excel")
    @RoleCheck(name = "dept_excel")
    public void doDownLoad(Integer parentId, HttpServletResponse response) throws IOException {
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode("部门信息文件"+ UUID.randomUUID().toString().replace("-", ""), "UTF-8");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
        SysDept evsApiDept = new SysDept();
        evsApiDept.setParentId(parentId);
        evsApiDept.setIncludeLower(true);
        List<SysDept> departments = evsHttpService.getDepartments(evsApiDept, evsHttpService.getToken());
        List<DeptExcelVO> excelVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(departments)) {
            List<SysDept> list = sysDeptService.getList(new SysDept());
            for (SysDept dept : list) {
                DeptExcelVO deptExcelVO = new DeptExcelVO();
                deptExcelVO.setDeptType(EnumDeptType.getByCode(dept.getDeptType()).getText());
                deptExcelVO.setAlarmCount(dept.getAlarmsCount());
                deptExcelVO.setDescription(dept.getRemark());
                deptExcelVO.setIsModel(dept.getIsModel() ? "是" : "否");
                deptExcelVO.setLatitude(dept.getLatitude());
                deptExcelVO.setLongitude(dept.getLongitude());
                deptExcelVO.setManagerId(dept.getUserId());
                deptExcelVO.setPoiId(dept.getPoiId());
                deptExcelVO.setPoiName(dept.getPoiName());
                deptExcelVO.setSiteArea(dept.getSiteArea());
                deptExcelVO.setUeArea(dept.getUeArea());
                Optional<SysDept> sysDept = departments.stream()
                        .filter(de -> de.getId().equals(dept.getId()))
                        .findFirst();
                if(sysDept.isPresent()){
                    deptExcelVO.setDeptName(sysDept.get().getName());
                }
                deptExcelVO.setId(dept.getId().intValue());
                excelVOList.add(deptExcelVO);
            }
        }
        ExcelWriterBuilder write = EasyExcel.write(response.getOutputStream(), DeptExcelVO.class);
        ExcelWriterSheetBuilder excelWriterSheetBuilder = write.sheet("部门信息");
        excelWriterSheetBuilder.doWrite(excelVOList);
    }


}
